package com.zhg.shortlink.service;

import com.zhg.shortlink.constant.RedisKeyConstants;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

/**
 * @author 朱洪刚
 * @version 1.0
 * @data 2025/10/21 09:38
 */
@Slf4j
@RequiredArgsConstructor
@Service
@Deprecated
public class RedisBloomFilterService {
    private final RedissonClient redissonClient;
    private final RedisTemplate<String, String> redisTemplate;

    // 布隆过滤器配置
    @Value("${shortlink.bloom.expected-insertions:10000000}")
    private long expectedInsertions;

    @Value("${shortlink.bloom.false-probability:0.01}")
    private double falseProbability;

    // 异步执行器
    private final Executor bloomFilterExecutor;

    private RBloomFilter<String> bloomFilter;

    @PostConstruct
    public void initBloomFilter() {
        try {
            // 使用统一的布隆过滤器名称
            bloomFilter = redissonClient.getBloomFilter(RedisKeyConstants.BLOOM_FILTER_NAME);

            // 如果布隆过滤器不存在，则初始化
            if (!bloomFilter.isExists()) {
                bloomFilter.tryInit(expectedInsertions, falseProbability);
                log.info("Redis布隆过滤器初始化完成: expectedInsertions={}, falseProbability={}",
                        expectedInsertions, falseProbability);
            }
        } catch (Exception e) {
            log.error("Redis布隆过滤器初始化失败", e);
            throw new RuntimeException("Redis布隆过滤器初始化失败", e);
        }
    }

    public boolean mightContain(String shortCode) {
        try {
            return bloomFilter.contains(shortCode);
        } catch (Exception e) {
            log.error("Redis布隆过滤器查询失败: shortCode={}", shortCode, e);
            return true;
        }
    }

    public void add(String shortCode) {
        try {
            bloomFilter.add(shortCode);
            // 同时添加到Redis Set，用于与本地布隆过滤器同步
            redisTemplate.opsForSet().add(RedisKeyConstants.BLOOM_SET_KEY, shortCode);
            log.debug("添加到Redis布隆过滤器: {}", shortCode);
        } catch (Exception e) {
            log.error("添加到Redis布隆过滤器失败: shortCode={}", shortCode, e);
        }
    }

    public void addAsync(String shortCode) {
        CompletableFuture.runAsync(() -> add(shortCode), bloomFilterExecutor)
                .exceptionally(throwable -> {
                    log.error("异步添加到Redis布隆过滤器失败: shortCode={}", shortCode, throwable);
                    return null;
                });
    }

    public void addBatch(java.util.List<String> shortCodes) {
        CompletableFuture.runAsync(() -> {
            try {
                for (String shortCode : shortCodes) {
                    bloomFilter.add(shortCode);
                }
                // 批量添加到Redis Set
                if (!shortCodes.isEmpty()) {
                    redisTemplate.opsForSet().add(RedisKeyConstants.BLOOM_SET_KEY,
                            shortCodes.toArray(new String[0]));
                }
                log.info("批量添加到Redis布隆过滤器完成: count={}", shortCodes.size());
            } catch (Exception e) {
                log.error("批量添加到Redis布隆过滤器失败", e);
            }
        }, bloomFilterExecutor);
    }

    public String getStats() {
        try {
            long count = bloomFilter.count();
            return String.format("Redis布隆过滤器统计 - 元素数量: %d, 预期容量: %d, 误判率: %.4f",
                    count, expectedInsertions, falseProbability);
        } catch (Exception e) {
            log.error("获取Redis布隆过滤器统计失败", e);
            return "统计信息获取失败";
        }
    }
}
